/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ctu.labiras.testador;

import br.ctu.labiras.utils.ArquivoUtils;
import java.util.ArrayList;
import java.util.Hashtable;

/**
 *
 * @author THIAGO
 */
public abstract class EstrategiaBase {
    public static int geracao = 0, max_gera, max_fit, repeticao, qLinhaColuna, max_interacoes;
    public static Double melhorFitness = 0.0;
    int N, L, Pm, CodAgente, QE;
    int[][] elementos = null;
    public static String path;
    static ArquivoUtils arquivo;
    static Populacao melhoresIndividuos =  new Populacao();
    static ArrayList<FuncaoAvaliacao> funcaoAvaliacao = new ArrayList<FuncaoAvaliacao>();
    //Representa os objetivos do agente (Chave: Objetivo; Valor: Peso)
    public static Hashtable<String, Double> objetivos = new Hashtable<String, Double>();
    
    protected abstract Populacao geraPopulacaoInicial();
           
    protected abstract Populacao obtemPopulacao(Populacao populacaoAnalisada);
    
    protected abstract void configuraParametros();
    
    public Populacao selecionaMelhores(Populacao populacao, Populacao melhoresAnt, int geracao) {
            
    	Populacao melhores = new Populacao();
		Double maiorFitness = obtemMelhorFitness(populacao); //Maior fitness da populacao atual
		Double maiorFitnessAnt = obtemMelhorFitness(melhoresAnt); //Maior fitness da populacao anterior

		//O melhor individuo eh aquele que possui o maior fitness
		//Verifica se os individuos da populacao anterior sao melhores que os da populacao atual
		//Se for, adiciona os individuos da populacao anterior na lista dos melhores individuos
		if (maiorFitnessAnt != null && maiorFitness != null && maiorFitnessAnt >= maiorFitness) {
			for(Individuo ind : melhoresAnt.getIndividuo()){
				if (ind.getAvaliacao() != null && ind.getAvaliacao() == maiorFitnessAnt &&
						!verificaMelhorIndividuoRepetido(melhores, ind) )
					melhores.getIndividuo().add(ind);
			}
		}
		
		//Verifica se os individuos da populacao atual sao melhores que a populacao anterior
		//Se for, adiciona os individuos da populacao atual na lista dos melhores individuos
		if (maiorFitnessAnt == null || (maiorFitness != null && maiorFitnessAnt != null) && 
				maiorFitness > maiorFitnessAnt)
		{
			for(Individuo ind : populacao.getIndividuo()){
				if (ind.getAvaliacao() != null && ind.getAvaliacao() == maiorFitness &&
						!verificaMelhorIndividuoRepetido(melhores, ind) )
					melhores.getIndividuo().add(ind);
			}
		}

		//arquivo.imprime1(geracao, populacao, obtemFitnessMedio(populacao), melhoresIndividuos);
		return melhores;
    }
    
    protected boolean verificaMelhorIndividuoRepetido(Populacao melhores, Individuo individuo) {
            for(Individuo ind : melhores.getIndividuo()) {
                    if (ind.getCenario().equals(individuo.getCenario())) {
                            return true;
                    }
            }
            return false;
    }
    
    protected Double obtemMelhorFitness(Populacao populacao) {
            Double melhorFitness = null;
            for(Individuo i : populacao.getIndividuo()) {

                    //Define o melhorFitness para o primeiro individuo
                    if (melhorFitness == null)
                            melhorFitness = i.getAvaliacao();

                    if (i.getAvaliacao() != null && i.getAvaliacao() > melhorFitness)
                            melhorFitness = i.getAvaliacao();
            }
            return melhorFitness;
    }
}
